home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Sound / AHI / Developer / support / Source / sift / sift.c
C/C++ Source or Header  |  1995-12-31  |  6KB  |  253 lines

  1. ;/* sift.c - Execute me to compile me with SAS C 5.10
  2. LC -b1 -cfistq -v -j73 sift.c
  3. Blink FROM LIB:c.o,sift.o TO sift LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. quit
  5.  
  6. *
  7. * sift.c:    Takes any IFF file and tells you what's in it.  Verifies
  8. *        syntax and all that cool stuff.
  9. *
  10. * Usage: sift -c        ; For clipboard scanning
  11. *    or  sift <file>        ; For DOS file scanning
  12. *
  13. * Reads the specified stream and prints an IFFCheck-like listing of the
  14. * contents of the IFF file, if any.  Stream is a DOS file for <file>
  15. * argument, or is the clipboard's primary clip for -c.
  16. * This program must be run from a CLI.
  17. *
  18. * Based on original sift.c by by Stuart Ferguson and Leo Schwab
  19. */
  20.  
  21. #include <exec/types.h>
  22. #include <exec/memory.h>
  23. #include <libraries/dos.h>
  24. #include <libraries/iffparse.h>
  25.  
  26. #include <clib/exec_protos.h>
  27. #include <clib/dos_protos.h>
  28. #include <clib/iffparse_protos.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32.  
  33. #ifdef LATTICE
  34. int CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */
  35. int chkabort(void) { return(0); }  /* really */
  36. #endif
  37.  
  38. #define MINARGS 2
  39.  
  40. /* 2.0 Version string for c:Version to find */
  41. UBYTE vers[] = "\0$VER: sift 37.1";
  42.  
  43. UBYTE usage[] = "Usage: sift IFFfilename (or -c for clipboard)";
  44.  
  45. /* proto for our function */
  46. void PrintTopChunk (struct IFFHandle *);
  47.  
  48. /*
  49.  * Text error messages for possible IFFERR_#? returns from various
  50.  * IFF routines.  To get the index into this array, take your IFFERR code,
  51.  * negate it, and subtract one.
  52.  *  idx = -error - 1;
  53.  */
  54. char    *errormsgs[] = {
  55.     "End of file (not an error).",
  56.     "End of context (not an error).",
  57.     "No lexical scope.",
  58.     "Insufficient memory.",
  59.     "Stream read error.",
  60.     "Stream write error.",
  61.     "Stream seek error.",
  62.     "File is corrupt.",
  63.     "IFF syntax error.",
  64.     "Not an IFF file.",
  65.     "Required call-back hook missing.",
  66.     "Return to client.  You should never see this."
  67. };
  68.  
  69. struct Library *IFFParseBase;
  70.  
  71.  
  72. void main(int argc, char **argv)
  73. {
  74.     struct IFFHandle    *iff = NULL;
  75.     long        error;
  76.     short        cbio;
  77.  
  78.         /* if not enough args or '?', print usage */
  79.         if(((argc)&&(argc<MINARGS))||(argv[argc-1][0]=='?'))
  80.         {
  81.             printf("%s\n",usage);
  82.             goto bye;
  83.             }
  84.  
  85.     /*
  86.      * Check to see if we are doing I/O to the Clipboard.
  87.      */
  88.     cbio = (argv[1][0] == '-'  &&  argv[1][1] == 'c');
  89.  
  90.     if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L)))
  91.         {
  92.         puts("Can't open iff parsing library.");
  93.         goto bye;
  94.         }
  95.  
  96.     /*
  97.      * Allocate IFF_File structure.
  98.      */
  99.     if (!(iff = AllocIFF ()))
  100.         {
  101.         puts ("AllocIFF() failed.");
  102.         goto bye;
  103.         }
  104.  
  105.     /*
  106.      * Internal support is provided for both AmigaDOS files, and the
  107.      * clipboard.device.  This bizarre 'if' statement performs the
  108.      * appropriate machinations for each case.
  109.      */
  110.     if (cbio)
  111.         {
  112.         /*
  113.          * Set up IFF_File for Clipboard I/O.
  114.          */
  115.         if (!(iff->iff_Stream =
  116.                 (ULONG) OpenClipboard (PRIMARY_CLIP)))
  117.             {
  118.             puts ("Clipboard open failed.");
  119.             goto bye;
  120.             }
  121.         InitIFFasClip (iff);
  122.         }
  123.     else
  124.         {
  125.         /*
  126.          * Set up IFF_File for AmigaDOS I/O.
  127.          */
  128.         if (!(iff->iff_Stream = Open (argv[1], MODE_OLDFILE)))
  129.             {
  130.             puts ("File open failed.");
  131.             goto bye;
  132.             }
  133.         InitIFFasDOS (iff);
  134.         }
  135.  
  136.     /*
  137.      * Start the IFF transaction.
  138.      */
  139.     if (error = OpenIFF (iff, IFFF_READ))
  140.         {
  141.         puts ("OpenIFF failed.");
  142.         goto bye;
  143.         }
  144.  
  145.     while (1)
  146.         {
  147.         /*
  148.          * The interesting bit.  IFFPARSE_RAWSTEP permits us to
  149.          * have precision monitoring of the parsing process, which
  150.          * is necessary if we wish to print the structure of an
  151.          * IFF file.  ParseIFF() with _RAWSTEP will return the
  152.          * following things for the following reasons:
  153.          *
  154.          * Return code:            Reason:
  155.          * 0                Entered new context.
  156.          * IFFERR_EOC            About to leave a context.
  157.          * IFFERR_EOF            Encountered end-of-file.
  158.          * <anything else>        A parsing error.
  159.          */
  160.         error = ParseIFF (iff, IFFPARSE_RAWSTEP);
  161.  
  162.         /*
  163.          * Since we're only interested in when we enter a context,
  164.          * we "discard" end-of-context (_EOC) events.
  165.          */
  166.         if (error == IFFERR_EOC)
  167.             continue;
  168.         else if (error)
  169.             /*
  170.              * Leave the loop if there is any other error.
  171.              */
  172.             break;
  173.  
  174.         /*
  175.          * If we get here, error was zero.
  176.          * Print out the current state of affairs.
  177.          */
  178.         PrintTopChunk (iff);
  179.         }
  180.  
  181.     /*
  182.      * If error was IFFERR_EOF, then the parser encountered the end of
  183.      * the file without problems.  Otherwise, we print a diagnostic.
  184.      */
  185.     if (error == IFFERR_EOF)
  186.         puts ("File scan complete.");
  187.     else
  188.         printf ("File scan aborted, error %ld: %s\n",
  189.             error, errormsgs[-error - 1]);
  190.  
  191. bye:
  192.     if (iff) {
  193.         /*
  194.          * Terminate the IFF transaction with the stream.  Free
  195.          * all associated structures.
  196.          */
  197.         CloseIFF (iff);
  198.  
  199.         /*
  200.          * Close the stream itself.
  201.          */
  202.         if (iff->iff_Stream)
  203.             if (cbio)
  204.                 CloseClipboard ((struct ClipboardHandle *)
  205.                         iff->iff_Stream);
  206.             else
  207.                 Close (iff->iff_Stream);
  208.  
  209.         /*
  210.          * Free the IFF_File structure itself.
  211.          */
  212.         FreeIFF (iff);
  213.         }
  214.     if (IFFParseBase)    CloseLibrary (IFFParseBase);
  215.  
  216.     exit (RETURN_OK);
  217. }
  218.  
  219.  
  220. void
  221. PrintTopChunk (iff)
  222. struct IFFHandle *iff;
  223. {
  224.     struct ContextNode    *top;
  225.     short            i;
  226.     char            idbuf[5];
  227.  
  228.     /*
  229.      * Get a pointer to the context node describing the current context.
  230.      */
  231.     if (!(top = CurrentChunk (iff)))
  232.         return;
  233.  
  234.     /*
  235.      * Print a series of dots equivalent to the current nesting depth of
  236.      * chunks processed so far.  This will cause nested chunks to be
  237.      * printed out indented.
  238.      */
  239.     for (i = iff->iff_Depth;  i--; )
  240.         printf (". ");
  241.  
  242.     /*
  243.      * Print out the current chunk's ID and size.
  244.      */
  245.     printf ("%s %ld ", IDtoStr (top->cn_ID, idbuf), top->cn_Size);
  246.  
  247.     /*
  248.      * Print the current chunk's type, with a newline.
  249.      */
  250.     puts (IDtoStr (top->cn_Type, idbuf));
  251. }
  252.  
  253.